package com.zzyl.framework.interceptor.impl;

import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.ThreadLocalUtil;
import com.zzyl.framework.web.service.TokenService;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Description MemberInterceptor
 * @Author cangyue
 * @Date 2025-07-19
 */
@Component
@Slf4j
public class MemberInterceptor implements HandlerInterceptor {
    @Resource
    private TokenService tokenService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 如果不是映射到方法直接通过
        if(!(handler instanceof HandlerMethod)){
            return true;
        }
        
        String requestURI = request.getRequestURI();
        String method = request.getMethod();
        log.info("=== MemberInterceptor 拦截请求：{} {} ===", method, requestURI);
        
        // 获取用户TOKEN
        String header = request.getHeader("Authorization");
        log.info("Authorization header: {}", header);

        if (header == null || header.isEmpty()){
            log.error("Authorization header 为空");
            response.setStatus(401);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"code\":401,\"msg\":\"请先登录\",\"data\":null}");
            return false;
        }
        
        // 处理token格式，前端可能直接发送token值，也可能发送Bearer token
        String token = header;
        if (header.startsWith("Bearer ")) {
            token = header.substring(7); // 移除Bearer前缀
            log.info("移除Bearer前缀后的token: {}", token);
        }
        
        try{
            Claims claims = tokenService.parseToken(token);
            log.info("Token解析成功，claims: {}", claims);
            Object idObj = claims.get("id");
            if (idObj == null) {
                log.error("Token中未找到id字段");
                response.setStatus(401);
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write("{\"code\":401,\"msg\":\"Token格式错误，请重新登录\",\"data\":null}");
                return false;
            }
            Long userId = Long.valueOf(idObj.toString());
            ThreadLocalUtil.set(userId);
            log.info("设置用户ID到ThreadLocal: {}", userId);

        }catch (Exception e){
            log.error("Token解析失败： "+e.getMessage(), e);
            response.setStatus(401);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("{\"code\":401,\"msg\":\"认证失败，请重新登录\",\"data\":null}");
            return false;
        }
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 清理ThreadLocal，防止内存泄漏
        ThreadLocalUtil.remove();
        log.info("=== MemberInterceptor 清理ThreadLocal ===");
    }
}
